package com.wb.business.utils;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.project.relation.constants.LoggerConstants;
import com.ruoyi.project.relation.domain.ao.SyncActionRequest;
import com.wb.business.config.BusinessEntityManager;
import com.wb.business.service.BusinessEntityService;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.shoukaiseki.common.exception.MessageVirtualException;
import org.shoukaiseki.common.utils.JacksonUtils;
import org.shoukaiseki.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.GenericTypeResolver;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;

/**
 *
 **/
public class SyncActionUtils {

    public static final Logger logger= LoggerConstants.SYNC_ACTION_LOGGER;

    /**
     * @param domain
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T domainToJavaBean(String domain,Class<T> clazz){
//        return JacksonUtils.json2pojo(domain,clazz);
        return JSONObject.parseObject(domain,clazz);
    }

    /**
     * json 转 list
     * @param domain
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> domainToJavaBeanList(String domain,Class<T> clazz){
        return JacksonUtils.json2list(domain,clazz);
    }


    /**
     * json 转 对象,支持 转为List<User>
     * @param domain
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T domainToJavaBeanForType(String domain,Type type){
        return JacksonUtils.json2PojoForType(domain,type);
    }

    public static <T> T invokeBeanName(BusinessEntityService businessEntityService,  SyncActionRequest syncActionRequest){
        String beanName=syncActionRequest.getBeanName();
        Method method = BusinessEntityManager.getMethod(businessEntityService.getTableName(), beanName);

        Type[] genericParameterTypes = method.getGenericParameterTypes();
//        Class<?>[] parameterTypes = method.getParameterTypes();
        if (genericParameterTypes.length!=1) {
            throw new RuntimeException(syncActionRequest.getOwnerName()+"["+syncActionRequest.getBeanName()+"]调用的方法需要多个参数,请修改 syncAction 方法");
        }
        Type genericParameterType = genericParameterTypes[0];
//        Class<?> parameterType = parameterTypes[0];
//        if (parameterType.equals(List.class)) {
//            Type genericSuperclass = parameterType.getGenericSuperclass();
//
//        }
        Object obj = domainToJavaBeanForType(syncActionRequest.getDomain(), genericParameterType);
//        List<?> objects = SyncActionUtils.domainToJavaBeanList(syncActionRequest.getDomain(), parameterType);
//        Object objects = SyncActionUtils.domainToJavaBean(syncActionRequest.getDomain(), parameterType);
        try {
            Object invoke = method.invoke(businessEntityService, obj);
            return (T) invoke;
        } catch (Exception e) {
            logger.warn(StringUtils.format("{}[{}]方法调用出错",businessEntityService.getTableName(),beanName),e);
//            if(e instanceof MessageVirtualException){
                throw new RuntimeException(formatMethodExceptionMessage(e));
//            }else{
//                throw new RuntimeException(businessEntityService.getTableName()+"["+beanName+"]方法调用出错",e);
//            }
        }
    }


    public static String formatMethodExceptionMessage(Throwable t){
        if(t instanceof MessageVirtualException){
            return t.getMessage();
        }else if(t instanceof InvocationTargetException){
            Throwable targetException = ((InvocationTargetException) t).getTargetException();
            if(targetException!=null){
                return targetException.getMessage();
            }
        }
        return t.getMessage();
    }
}
